home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / hobby / ast44src.zip / ASTROLOG.C next >
C/C++ Source or Header  |  1995-02-11  |  45KB  |  1,686 lines

  1. /*
  2. ** Astrolog (Version 4.40) File: astrolog.c
  3. **
  4. ** IMPORTANT NOTICE: The graphics database and chart display routines
  5. ** used in this program are Copyright (C) 1991-1995 by Walter D. Pullen
  6. ** (astara@u.washington.edu). Permission is granted to freely use and
  7. ** distribute these routines provided one doesn't sell, restrict, or
  8. ** profit from them in any way. Modification is allowed provided these
  9. ** notices remain with any altered or edited versions of the program.
  10. **
  11. ** The main planetary calculation routines used in this program have
  12. ** been Copyrighted and the core of this program is basically a
  13. ** conversion to C of the routines created by James Neely as listed in
  14. ** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
  15. ** available from Matrix Software. The copyright gives us permission to
  16. ** use the routines for personal use but not to sell them or profit from
  17. ** them in any way.
  18. **
  19. ** The PostScript code within the core graphics routines are programmed
  20. ** and Copyright (C) 1992-1993 by Brian D. Willoughby
  21. ** (brianw@sounds.wa.com). Conditions are identical to those above.
  22. **
  23. ** The extended accurate ephemeris databases and formulas are from the
  24. ** calculation routines in the program "Placalc" and are programmed and
  25. ** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
  26. ** (alois@azur.ch). The use of that source code is subject to
  27. ** regulations made by Astrodienst Zurich, and the code is not in the
  28. ** public domain. This copyright notice must not be changed or removed
  29. ** by any user of this program.
  30. **
  31. ** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
  32. ** X Window graphics initially programmed 10/23-29/1991.
  33. ** PostScript graphics initially programmed 11/29-30/1992.
  34. ** Last code change made 1/29/1995.
  35. */
  36.  
  37. #include "astrolog.h"
  38.  
  39.  
  40. /*
  41. ******************************************************************************
  42. ** Program Dispatch Procedures.
  43. ******************************************************************************
  44. */
  45.  
  46. /* Initialize the Ansi color arrays with the color to print each object in. */
  47.  
  48. void InitColors()
  49. {
  50.   int i;
  51.  
  52.   kObjA[0] = kElemA[eEar];
  53.   for (i = 1; i <= 10; i++)
  54.     kObjA[i] = kSignA(ruler1[i]);
  55.   for (i = 11; i <= 15; i++)
  56.     kObjA[i] = kMainA[8];
  57.   for (i = 16; i <= 20; i++)
  58.     kObjA[i] = kMainA[6];
  59.   for (i = 1; i <= cSign; i++)
  60.     kObjA[cuspLo+i-1] = kSignA(i);
  61.   for (i = uranLo; i <= uranHi; i++)
  62.     kObjA[i] = kRainbowA[7];
  63.   for (i = starLo; i <= starHi; i++)
  64.     kObjA[i] = starbright[i-oNorm] < 1.0 ? kRainbowA[2] : kMainA[4];
  65. }
  66.  
  67.  
  68. /* This is the dispatch procedure for the entire program. After all the   */
  69. /* command switches have been processed, this routine is called to        */
  70. /* actually call the various routines to generate and display the charts. */
  71.  
  72. void Action()
  73. {
  74.   char sz[cchSzDef];
  75.   int i;
  76.  
  77.   is.fSzPersist = fFalse;
  78.   is.cchRow = 0;
  79.   AnsiColor(kDefault);
  80.   InitColors();
  81.   if (fSouthNode) {
  82.     szObjName[oSou] = "S.Node";
  83. #ifdef INTERPRET
  84.     szMindPart[oSou] =
  85.       "karmic past, and area of experience but little growth";
  86. #endif
  87.     ruler1[oSou] = sLeo;
  88.   }
  89.   if (us.fParallel) {
  90.     szAspectAbbrev[aCon] = "Par"; szAspectAbbrev[aOpp] = "CPr";
  91.   }
  92.  
  93.   /* First let's adjust the restriction status of the cusps, uranians, and */
  94.   /* fixed stars based on whether -C, -u, and -U switches are in effect.   */
  95.  
  96.   if (!us.fCusp)
  97.     for (i = cuspLo; i <= cuspHi; i++)
  98.       ignore[i] = ignore2[i] = fTrue;
  99.   if (!us.fUranian)
  100.     for (i = uranLo; i <= uranHi; i++)
  101.       ignore[i] = ignore2[i] = fTrue;
  102.   if (!us.nStar)
  103.     for (i = starLo; i <= starHi; i++)
  104.       ignore[i] = ignore2[i] = fTrue;
  105.  
  106.   /* If the -os switch is in effect, open a file and set a global to */
  107.   /* internally 'redirect' all screen output to.                     */
  108.  
  109.   if (is.szFileScreen) {
  110.     S = fopen(is.szFileScreen, "w");
  111.     if (S == NULL) {
  112.       sprintf(sz, "File %s can not be created.", is.szFileScreen);
  113.       PrintError(sz);
  114.       S = stdout;
  115.     }
  116.   } else
  117.     S = stdout;
  118.  
  119.   if (FPrintTables())    /* Print out any generic tables specified.        */
  120.     return;              /* If nothing else to do, we can exit right away. */
  121.   if (is.fMult) {
  122.     PrintL2();
  123.     is.fMult = fFalse;
  124.   }
  125.  
  126.   /* If -+ or -- switches in effect, then add the specified delta value to */
  127.   /* the date and use that as a new date before proceeding to make chart.  */
  128.  
  129.   if (us.dayDelta != 0) {
  130.     is.JD = (real)MdyToJulian(MM, DD+us.dayDelta, YY);
  131.     JulianToMdy(is.JD, &MM, &DD, &YY);
  132.   }
  133.  
  134.   /* Here we either do a normal chart or some kind of relationship chart. */
  135.  
  136.   if (!us.nRel) {
  137.     /* If chart info not in memory yet, then prompt the user for it. */
  138.     if (!is.fHaveInfo && !FInputData(szTtyCore))
  139.       return;
  140.     CastChart(fTrue);
  141.     ciMain = ciCore;
  142.   } else
  143.     CastRelation(fTrue);
  144.   ciSave = ciMain;
  145.  
  146. #ifdef GRAPH
  147.   if (us.fGraphics)         /* If any of the X window switches in effect, */
  148.     FActionX();             /* then go make a graphics chart...           */
  149.   else
  150. #endif
  151.     PrintChart(is.fProgress);    /* Otherwise print chart on text screen. */
  152.  
  153.   if (us.fWriteFile)        /* If -o switch in effect, then write */
  154.     FOutputData();          /* the chart information to a file.   */
  155.  
  156.   if (S != stdout)    /* If we were internally directing chart display to a */
  157.     fclose(S);        /* file as with the -os switch, close it here.        */
  158.  
  159.   if (grid)
  160.     DeallocateFar(grid);
  161. }
  162.  
  163.  
  164. /* Reset a few variables to their default values they have upon startup of */
  165. /* the program. We don't reset all variables, just the most volatile ones. */
  166. /* This is called when in the -Q loop to reset things like which charts to */
  167. /* display, but leave setups such as object restrictions and orbs alone.   */
  168.  
  169. void InitVariables()
  170. {
  171.   us.fInterpret = us.fProgress = is.fHaveInfo = is.fMult = fFalse;
  172.   us.nRel = us.dayDelta = 0;
  173.   is.szFileScreen = NULL;
  174.   ClearB((lpbyte)&us.fListing,
  175.     (int)((lpbyte)&us.fLoop - (lpbyte)&us.fListing));
  176. }
  177.  
  178.  
  179. /*
  180. ******************************************************************************
  181. ** Command Switch Procedures.
  182. ******************************************************************************
  183. */
  184.  
  185. /* Given a string representing a command line (e.g. a macro string), go    */
  186. /* parse it into its various switches and parameters, then go process them */
  187. /* and change program settings. Basically a wrapper for other functions.   */
  188.  
  189. bool FProcessCommandLine(szLine)
  190. char *szLine;
  191. {
  192.   char szCommandLine[cchSzMax], *rgsz[MAXSWITCHES];
  193.   int argc, cb, fT;
  194.  
  195.   if (szLine == NULL)
  196.     return fTrue;
  197.   if (Mon != -1)
  198.     ciCore = ciMain;
  199.   cb = CchSz(szLine)+1;
  200.   CopyRgb((byte *)szLine, (byte *)szCommandLine, cb);
  201.   argc = NParseCommandLine(szCommandLine, rgsz);
  202.   fT = FProcessSwitches(argc, rgsz);
  203.   ciMain = ciCore;
  204.   return fT;
  205. }
  206.  
  207.  
  208. /* Given string representing a command line, convert it to an "argv" format */
  209. /* of an array of strings, one for each switch or parameter, i.e. exactly   */
  210. /* like the format of the command line as given when the program starts.    */
  211.  
  212. int NParseCommandLine(szLine, argv)
  213. char *szLine;
  214. char **argv;
  215. {
  216.   int argc = 1, fSpace = fTrue, fQuote = fFalse;
  217.   char *pch = szLine;
  218.  
  219.   /* Split the entered line up into its individual switch strings. */
  220.   while (*pch >= ' ' || *pch == chTab) {
  221.     if (*pch == ' ' || *pch == chTab) {
  222.       if (fSpace)
  223.         /* Skip over the current run of spaces between strings. */
  224.         ;
  225.       else {
  226.         /* First space after a string, end parameter here. */
  227.         if (!fQuote) {
  228.           *pch = chNull;
  229.           fSpace = fTrue;
  230.         }
  231.       }
  232.     } else {
  233.       if (fSpace) {
  234.         /* First character after run of spaces, begin parameter here. */
  235.         if (argc >= MAXSWITCHES-1) {
  236.           PrintWarning("Too many items - rest of line ignored.");
  237.           break;
  238.         }
  239.         fQuote = (*pch == '"');
  240.         argv[argc++] = pch + fQuote;
  241.         fSpace = fFalse;
  242.       } else
  243.         /* Skip over the current string. */
  244.         if (fQuote && *pch == '"') {
  245.           *pch = chNull;
  246.           fSpace = fTrue;
  247.         }
  248.     }
  249.     pch++;
  250.   }
  251.   argv[0] = szAppNameCore;
  252.   argv[argc] = NULL;         /* Set last string in switch array to Null. */
  253.   return argc;
  254. }
  255.  
  256.  
  257. /* This routine is called by the main program to interactively prompt the  */
  258. /* user for command switches and parameters, entered in the same format as */
  259. /* they would be on a command line. This needs to be called with certain   */
  260. /* systems which don't allow passing of a command line to the program,     */
  261. /* or when -Q is in effect. The result of this routine is returned to the  */
  262. /* main program which then processes it as done with a real command line.  */
  263.  
  264. int NPromptSwitches(line, argv)
  265. char *line, *argv[MAXSWITCHES];
  266. {
  267.   FILE *data;
  268.   char sz[cchSzDef];
  269.  
  270.   data = S; S = stdout;
  271.   is.cchRow = 0;
  272.   AnsiColor(kWhite);
  273.   sprintf(sz, "** %s version %s ", szAppName, szVersionCore); PrintSz(sz);
  274.   sprintf(sz, "(See '%cHc' switch for copyrights and credits.) **\n",
  275.     chSwitch); PrintSz(sz);
  276.   AnsiColor(kDefault);
  277.   PrintSz("Enter all parameter options below. ");
  278.   sprintf(sz, "(Enter '%cH' for help. Enter '.' to exit.)\n", chSwitch);
  279.   PrintSz(sz);
  280.   S = data;
  281.   InputString("Input command line", line);
  282.   PrintL();
  283.   return NParseCommandLine(line, argv);
  284. }
  285.  
  286.  
  287. /* This subprocedure is like FProcessSwitches() below, except that we only */
  288. /* process one switch, which we know to be one of the obscure -Y types.    */
  289.  
  290. int NProcessSwitchesRare(argc, argv, pos, fOr, fAnd, fNot)
  291. int argc, pos;
  292. bool fOr, fAnd, fNot;
  293. char **argv;
  294. {
  295.   int darg = 0, i, j, k;
  296.   real r;
  297.   char ch1, ch2;
  298.   OE oe;
  299.   lpbyte lpb;
  300.   int FAR *lpn;
  301.   lpreal lpr;
  302. #ifdef INTERPRET
  303.   char *sz;
  304. #endif
  305.  
  306.   ch1 = argv[0][pos+1]; ch2 = argv[0][pos+2];
  307.   switch (argv[0][pos]) {
  308.   case chNull:
  309.     SwitchF(us.fSwitchRare);
  310.     break;
  311.  
  312.   case 'n':
  313.     SwitchF(us.fTrueNode);
  314.     break;
  315.  
  316.   case 'd':
  317.     SwitchF(us.fEuroDate);
  318.     break;
  319.  
  320.   case 't':
  321.     SwitchF(us.fEuroTime);
  322.     break;
  323.  
  324.   case 'C':
  325.     SwitchF(us.fSmartCusp);
  326.     break;
  327.  
  328.   case '8':
  329.     SwitchF(us.fClip80);
  330.     break;
  331.  
  332.   case 'Q':
  333.     if (argc <= 1) {
  334.       ErrorArgc("YQ");
  335.       return tcError;
  336.     }
  337.     i = atoi(argv[1]);
  338.     if (i < 0) {
  339.       ErrorValN("YQ", i);
  340.       return tcError;
  341.     }
  342.     us.nScrollRow = i;
  343.     darg++;
  344.     break;
  345.  
  346.   case 'o':
  347.     SwitchF(us.fWriteOld);
  348.     break;
  349.  
  350. #ifdef ARABIC
  351.   case 'P':
  352.     if (argc <= 1) {
  353.       ErrorArgc("YP");
  354.       return tcError;
  355.     }
  356.     i = atoi(argv[1]);
  357.     if (!FBetween(i, -1, 1)) {
  358.       ErrorValN("YP", i);
  359.       return tcError;
  360.     }
  361.     us.nArabicNight = i;
  362.     darg++;
  363.     break;
  364. #endif
  365.  
  366.   case 'E':
  367.     if (argc <= 17) {
  368.       ErrorArgc("YE");
  369.       return tcError;
  370.     }
  371.     i = NParseSz(argv[1], pmObject);
  372.     if (!FHelio(i)) {
  373.       ErrorValN("YE", i);
  374.       return tcError;
  375.     }
  376.     oe.sma = atof(argv[2]);
  377.     oe.ec0 = atof(argv[3]);  oe.ec1 = atof(argv[4]);  oe.ec2 = atof(argv[5]);
  378.     oe.in0 = atof(argv[6]);  oe.in1 = atof(argv[7]);  oe.in2 = atof(argv[8]);
  379.     oe.ap0 = atof(argv[9]);  oe.ap1 = atof(argv[10]); oe.ap2 = atof(argv[11]);
  380.     oe.an0 = atof(argv[12]); oe.an1 = atof(argv[13]); oe.an2 = atof(argv[14]);
  381.     oe.ma0 = atof(argv[15]); oe.ma1 = atof(argv[16]); oe.ma2 = atof(argv[17]);
  382.     rgoe[IoeFromObj(i)] = oe;
  383.     darg += 17;
  384.     break;
  385.  
  386.   case 'R':
  387.     if (argc <= 2) {
  388.       ErrorArgc("YR");
  389.       return tcError;
  390.     }
  391.     i = NParseSz(argv[1], pmObject); j = NParseSz(argv[2], pmObject);
  392.     if (ch1 == '0') {
  393.       ignore[0]  = i != 0;
  394.       ignore2[0] = j != 0;
  395.       darg += 2;
  396.       break;
  397.     }
  398.     if (!FItem(i)) {
  399.       ErrorValN("YR", i);
  400.       return tcError;
  401.     }
  402.     if (!FItem(j) || j < i) {
  403.       ErrorValN("YR", j);
  404.       return tcError;
  405.     }
  406.     if (argc <= 3+j-i) {
  407.       ErrorArgc("YR");
  408.       return tcError;
  409.     }
  410.     lpb = ch1 == 'T' ? ignore2 : ignore;
  411.     for (k = i; k <= j; k++)
  412.       lpb[k] = atoi(argv[3+k-i]) != 0;
  413.     darg += 3+j-i;
  414.     break;
  415.  
  416.   case 'A':
  417.     if (argc <= 2) {
  418.       ErrorArgc("YA");
  419.       return tcError;
  420.     }
  421.     k = ch1 == 'm' || ch1 == 'd' ? pmObject : pmAspect;
  422.     i = NParseSz(argv[1], k); j = NParseSz(argv[2], k);
  423.     k = ch1 == 'm' || ch1 == 'd' ? cObj : cAspect;
  424.     if (!FBetween(i, 1, k)) {
  425.       ErrorValN("YA", i);
  426.       return tcError;
  427.     }
  428.     if (!FBetween(j, 1, k) || j < i) {
  429.       ErrorValN("YA", j);
  430.       return tcError;
  431.     }
  432.     if (argc <= 3+j-i) {
  433.       ErrorArgc("YA");
  434.       return tcError;
  435.     }
  436.     lpr = ch1 == 'm' ? planetorb : (ch1 == 'd' ? planetadd : aspectorb);
  437.     for (k = i; k <= j; k++)
  438.       lpr[k] = atof(argv[3+k-i]);
  439.     darg += 3+j-i;
  440.     break;
  441.  
  442.   case 'j':
  443.     if (argc <= 2 + 2*(ch1 == '0')) {
  444.       ErrorArgc("Yj");
  445.       return tcError;
  446.     }
  447.     if (ch1 == '0') {
  448.       objectinf[oNorm+1] = atof(argv[1]);
  449.       objectinf[oNorm+2] = atof(argv[2]);
  450.       houseinf[cSign+1]  = atof(argv[3]);
  451.       houseinf[cSign+2]  = atof(argv[4]);
  452.       darg += 4;
  453.       break;
  454.     }
  455.     k = ch1 == 'C' ? pmSign : (ch1 == 'A' ? pmAspect : pmObject);
  456.     i = NParseSz(argv[1], k); j = NParseSz(argv[2], k);
  457.     k = ch1 == 'C' ? cSign : (ch1 == 'A' ? cAspect : cObj);
  458.     if (!FBetween(i, 1, k)) {
  459.       ErrorValN("Yj", i);
  460.       return tcError;
  461.     }
  462.     if (!FBetween(j, 1, k) || j < i) {
  463.       ErrorValN("Yj", j);
  464.       return tcError;
  465.     }
  466.     if (argc <= 3+j-i) {
  467.       ErrorArgc("Yj");
  468.       return tcError;
  469.     }
  470.     lpr = ch1 == 'C' ? houseinf : (ch1 == 'A' ? aspectinf :
  471.       (ch1 == 'T' ? transitinf : objectinf));
  472.     for (k = i; k <= j; k++)
  473.       lpr[k] = atof(argv[3+k-i]);
  474.     darg += 3+j-i;
  475.     break;
  476.  
  477. #ifdef INTERPRET
  478.   case 'I':
  479.     if (argc <= 2) {
  480.       ErrorArgc("YI");
  481.       return tcError;
  482.     }
  483.     i = NParseSz(argv[1],
  484.       ch1 == 'A' ? pmAspect : (ch1 == chNull ? pmObject : pmSign));
  485.     j = ch1 == 'A' ? cAspect : (ch1 == chNull ? oNorm : cSign);
  486.     if (!FBetween(i, 1, j)) {
  487.       ErrorValN("YI", i);
  488.       return tcError;
  489.     }
  490.     if (ch1 == 'A' && ch2 == '0')
  491.       ch1 = '0';
  492.     sz = SzPersist(argv[2]);
  493.     switch (ch1) {
  494.     case 'A':    szInteract[i]  = sz; break;
  495.     case '0':    szTherefore[i] = sz; break;
  496.     case chNull: szMindPart[i]  = sz; break;
  497.     case 'C':    szLifeArea[i]  = sz; break;
  498.     case 'v':    szDesire[i]    = sz; break;
  499.     default:     szDesc[i]      = sz;
  500.     }
  501.     darg += 2;
  502.     break;
  503. #endif
  504.  
  505.   case 'k':
  506.     if (argc <= 2 + 2*(ch1 == 'C')) {
  507.       ErrorArgc("Yk");
  508.       return tcError;
  509.     }
  510.     if (ch1 == 'C') {
  511.       kElemA[eFir] = NParseSz(argv[1], pmColor) & 15;
  512.       kElemA[eEar] = NParseSz(argv[2], pmColor) & 15;
  513.       kElemA[eAir] = NParseSz(argv[3], pmColor) & 15;
  514.       kElemA[eWat] = NParseSz(argv[4], pmColor) & 15;
  515.       darg += 4;
  516.       break;
  517.     }
  518.     k = ch1 == 'A' ? pmAspect : 0;
  519.     i = NParseSz(argv[1], k); j = NParseSz(argv[2], k);
  520.     k = ch1 == 'A' ? cAspect : (ch1 == '0' ? 7 : 8);
  521.     if (!FBetween(i, ch1 != chNull, k)) {
  522.       ErrorValN("Yk", i);
  523.       return tcError;
  524.     }
  525.     if (!FBetween(j, ch1 != chNull, k) || j < i) {
  526.       ErrorValN("Yk", j);
  527.       return tcError;
  528.     }
  529.     if (argc <= 3+j-i) {
  530.       ErrorArgc("Yk");
  531.       return tcError;
  532.     }
  533.     lpn = ch1 == 'A' ? kAspA : (ch1 == '0' ? kRainbowA : kMainA);
  534.     for (k = i; k <= j; k++)
  535.       lpn[k] = NParseSz(argv[3+k-i], pmColor) & 15;
  536.     darg += 3+j-i;
  537.     break;
  538.  
  539.   case 'F':
  540.     if (argc <= 8) {
  541.       ErrorArgc("YF");
  542.       return tcError;
  543.     }
  544.     i = NParseSz(argv[1], pmObject);
  545.     if (!FItem(i)) {
  546.       ErrorValN("YF", i);
  547.       return tcError;
  548.     }
  549.     r = Mod((real)(atoi(argv[2]) +
  550.       (NParseSz(argv[3], pmSign)-1)*30) + atof(argv[4])/60.0);
  551.     if (!FCusp(i))
  552.       planet[i] = r;
  553.     else {
  554.       j = Mod12(i-(cuspLo-1)+6);
  555.       if (FBetween(i, cuspLo-1+4, cuspLo-1+9)) {
  556.         house[i-(cuspLo-1)] = r;
  557.         house[j] = Mod(r + rDegHalf);
  558.       } else {
  559.         planet[i] = r;
  560.         planet[cuspLo-1+j] = Mod(r + rDegHalf);
  561.       }
  562.     }
  563.     j = atoi(argv[5]);
  564.     r = (j < 0 ? -1.0 : 1.0)*((real)abs(j) + atof(argv[6])/60.0);
  565.     planetalt[i] = Mod((r + rDegQuad) * 2.0) / 2.0 - rDegQuad;
  566.     ret[i] = RFromD(atof(argv[7]));
  567.     if (i <= oNorm)
  568.       SphToRec(atof(argv[8]), planet[i], planetalt[i],
  569.         &spacex[i], &spacey[i], &spacez[i]);
  570.     MM = -1;
  571.     darg += 8;
  572.     break;
  573.  
  574. #ifdef GRAPH
  575.   case 'X':
  576.     return NProcessSwitchesRareX(argc, argv, pos+1);
  577. #endif
  578.  
  579.   default:
  580.     ErrorSwitch(argv[0]);
  581.     return tcError;
  582.   }
  583.   return darg;    /* Return the value to be added to argc. */
  584. }
  585.  
  586.  
  587. /* Process a command switch line passed to the program. Read each entry in */
  588. /* the argument list and set all the program modes and charts to display.  */
  589.  
  590. bool FProcessSwitches(argc, argv)
  591. int argc;
  592. char **argv;
  593. {
  594.   int ich, i, j;
  595.   bool fNot, fOr, fAnd;
  596.   real rT;
  597.   char ch1, ch2, *pch;
  598.  
  599.   argc--; argv++;
  600.   while (argc) {
  601.     ch1 = argv[0][0];
  602.     fNot = fOr = fAnd = fFalse;
  603.     switch (ch1) {
  604.     case '=': fOr  = fTrue; break;
  605.     case '_': fAnd = fTrue; break;
  606.     case ':':               break;
  607.     default:  fNot = fTrue; break;
  608.     }
  609.     ich = 1 + FChSwitch(argv[0][0]);    /* Leading dash? */
  610.     ch1 = argv[0][ich];
  611.     ch2 = ch1 == chNull ? chNull : argv[0][ich+1];
  612.     switch (argv[0][ich-1]) {
  613.  
  614.     case 'H':
  615.       if (ch1 == 'c')
  616.         SwitchF(us.fCredit);
  617.       else if (ch1 == 'Y')
  618.         SwitchF(us.fSwitchRare);
  619. #ifdef ISG
  620.       else if (ch1 == 'X')
  621.         SwitchF(us.fKeyGraph);
  622. #endif
  623.       else if (ch1 == 'C')
  624.         SwitchF(us.fSign);
  625.       else if (ch1 == 'O')
  626.         SwitchF(us.fObject);
  627.       else if (ch1 == 'A')
  628.         SwitchF(us.fAspect);
  629.       else if (ch1 == 'F')
  630.         SwitchF(us.fConstel);
  631.       else if (ch1 == 'S')
  632.         SwitchF(us.fOrbitData);
  633.       else if (ch1 == 'I')
  634.         SwitchF(us.fMeaning);
  635.       else if (ch1 == 'e') {
  636.         SwitchF(us.fCredit); SwitchF(us.fSwitch); SwitchF(us.fSwitchRare);
  637.         SwitchF(us.fKeyGraph); SwitchF(us.fSign); SwitchF(us.fObject);
  638.         SwitchF(us.fAspect); SwitchF(us.fConstel); SwitchF(us.fOrbitData);
  639.         SwitchF(us.fMeaning);
  640.       } else
  641.         SwitchF(us.fSwitch);
  642.       break;
  643.  
  644.     case 'Q':
  645.       if (ch1 == '0')
  646.         SwitchF(us.fLoopInit);
  647.       SwitchF(us.fLoop);
  648.       break;
  649.  
  650.     case 'M':
  651.       i = (ch1 == '0');
  652.       if (argc <= 1+i) {
  653.         ErrorArgc("M");
  654.         return fFalse;
  655.       }
  656.       j = atoi(argv[1]);
  657.       if (!FValidMacro(j)) {
  658.         ErrorValN("M", j);
  659.         return fFalse;
  660.       }
  661.       j--;
  662.       if (i)
  663.         szMacro[j] = SzPersist(argv[2]);
  664.       else
  665.         FProcessCommandLine(szMacro[j]);
  666.       argc -= 1+i; argv += 1+i;
  667.       break;
  668.  
  669.     case 'Y':
  670.       i = NProcessSwitchesRare(argc, argv, ich, fOr, fAnd, fNot);
  671.       if (i < 0)
  672.         return fFalse;
  673.       argc -= i; argv += i;
  674.       break;
  675.  
  676.     /* Switches which determine the type of chart to display: */
  677.  
  678.     case 'v':
  679.       if (ch1 == '0')
  680.         SwitchF(us.fVelocity);
  681.       SwitchF(us.fListing);
  682.       break;
  683.  
  684.     case 'w':
  685.       if (ch1 == '0')
  686.         SwitchF(us.fWheelReverse);
  687.       if (argc > 1 && (i = atoi(argv[1]))) {
  688.         argc--; argv++;
  689.         if (!FValidWheel(i)) {
  690.           ErrorValN("w", i);
  691.           return fFalse;
  692.         }
  693.         us.nWheelRows = i;
  694.       }
  695.       SwitchF(us.fWheel);
  696.       break;
  697.  
  698.     case 'g':
  699.       if (ch1 == '0' || ch2 == '0')
  700.         SwitchF(us.fGridConfig);
  701.       if (ch1 == 'a')
  702.         SwitchF(us.fAppSep);
  703.       else if (ch1 == 'p')
  704.         SwitchF(us.fParallel);
  705. #ifdef X11
  706.       else if (ch1 == 'e') {
  707.         if (argc <= 1) {
  708.           ErrorArgc("geometry");
  709.           return fFalse;
  710.         }
  711.         gs.xWin = atoi(argv[1]);
  712.         if (argc > 2 && (gs.yWin = atoi(argv[2]))) {
  713.           argc--; argv++;
  714.         } else
  715.           gs.yWin = gs.xWin;
  716.         if (!FValidGraphx(gs.xWin)) {
  717.           ErrorValN("geometry", gs.xWin);
  718.           return fFalse;
  719.         }
  720.         if (!FValidGraphy(gs.yWin)) {
  721.           ErrorValN("geometry", gs.yWin);
  722.           return fFalse;
  723.         }
  724.         argc--; argv++;
  725.         break;
  726.       }
  727. #endif
  728.       SwitchF(us.fGrid);
  729.       break;
  730.  
  731.     case 'a':
  732.       SwitchF(us.fAspList);
  733.       if (ch1 == '0') {
  734.         SwitchF(us.fAspSummary);
  735.         ch1 = ch2;
  736.       }
  737.       if (ch1 == 'a')
  738.         SwitchF(us.fAppSep);
  739.       else if (ch1 == 'p')
  740.         SwitchF(us.fParallel);
  741.       break;
  742.  
  743.     case 'm':
  744.       if (ch1 == '0')
  745.         SwitchF(us.fMidSummary);
  746.       SwitchF(us.fMidpoint);
  747.       break;
  748.  
  749.     case 'Z':
  750.       if (ch1 == '0')
  751.         SwitchF(us.fPrimeVert);
  752.       else if (ch1 == 'd')
  753.         SwitchF(us.fHorizonSearch);
  754.       SwitchF(us.fHorizon);
  755.       break;
  756.  
  757.     case 'S':
  758.       SwitchF(us.fOrbit);
  759.       break;
  760.  
  761.     case 'j':
  762.       if (ch1 == '0')
  763.         SwitchF(us.fInfluenceSign);
  764.       SwitchF(us.fInfluence);
  765.       break;
  766.  
  767.     case 'L':
  768.       if (ch1 == '0')
  769.         SwitchF(us.fLatitudeCross);
  770.       if (argc > 1 && (i = atoi(argv[1]))) {
  771.         argc--; argv++;
  772.         if (i < 1 || 160%i > 0) {
  773.           ErrorValN("L", i);
  774.           return fFalse;
  775.         }
  776.         us.nAstroGraphStep = i;
  777.       }
  778.       SwitchF(us.fAstroGraph);
  779.       break;
  780.  
  781.     case 'K':
  782.       if (ch1 == 'y')
  783.         SwitchF(us.fCalendarYear);
  784.       SwitchF(us.fCalendar);
  785.       break;
  786.  
  787.     case 'd':
  788.       if (ch1 == 'p') {
  789.         i = (ch2 == 'y') + 2*(ch2 == 'Y');
  790. #ifdef TIME
  791.         j = i < 2 && (argv[0][ich+i+1] == 'n');
  792. #else
  793.         j = fFalse;
  794. #endif
  795.         if (!j && argc <= 2-(i&1)) {
  796.           ErrorArgc("dp");
  797.           return fFalse;
  798.         }
  799.         is.fProgress = us.fInDayMonth = fTrue;
  800.         Dst2 = us.dstDef; Zon2 = us.zonDef;
  801.         Lon2 = us.lonDef; Lat2 = us.latDef;
  802. #ifdef TIME
  803.         if (j)
  804.           GetTimeNow(&Mon2, &Day2, &Yea2, &Tim2, Zon2-Dst2);
  805. #endif
  806.         if (i) {
  807.           Mon2 = 0;
  808.           if (!j)
  809.             Yea2 = NParseSz(argv[1], pmYea);
  810.           us.nEphemYears = i == 2 ? atoi(argv[2]) : 1;
  811.         } else {
  812.           if (!j) {
  813.             Mon2 = NParseSz(argv[1], pmMon);
  814.             Yea2 = NParseSz(argv[2], pmYea);
  815.             if (!FValidMon(Mon2)) {
  816.               ErrorValN("dp", Mon2);
  817.               return fFalse;
  818.             }
  819.           }
  820.         }
  821.         if (!FValidYea(Yea2)) {
  822.           ErrorValN("dp", Yea2);
  823.           return fFalse;
  824.         }
  825.         if (!j) {
  826.           i = 2-(i&1);
  827.           argc -= i; argv += i;
  828.         }
  829.       } else if (ch1 == 'm' || ch1 == 'y' || ch1 == 'Y') {
  830.         if (ch1 == 'y')
  831.           us.nEphemYears = 1;
  832.         else if (ch1 == 'Y') {
  833.           if (argc <= 1) {
  834.             ErrorArgc("dY");
  835.             return fFalse;
  836.           }
  837.           i = atoi(argv[1]);
  838.           if (i < 1) {
  839.             ErrorValN("dY", i);
  840.             return fFalse;
  841.           }
  842.           us.nEphemYears = i;
  843.         }
  844.         SwitchF(us.fInDayMonth);
  845.         Mon2 = (ch1 == 'm');
  846.       }
  847. #ifdef X11
  848.       else if (ch1 == 'i') {    /* -display switch for X */
  849.         if (argc <= 1) {
  850.           ErrorArgc("display");
  851.           return fFalse;
  852.         }
  853.         gs.szDisplay = SzPersist(argv[1]);
  854.         argc--; argv++;
  855.         break;
  856.       }
  857. #endif
  858.       else if (argc > 1 && (i = atoi(argv[1]))) {
  859.         if (!FValidDivision(i)) {
  860.           ErrorValN("d", i);
  861.           return fFalse;
  862.         }
  863.         us.nDivision = i;
  864.         argc--; argv++;
  865.       }
  866.       SwitchF(us.fInDay);
  867.       break;
  868.  
  869.     case 'D':
  870.       SwitchF(us.fInDayInf);
  871.       break;
  872.  
  873.     case 'E':
  874.       if (ch1 == 'Y' && argc <= 1) {
  875.         ErrorArgc("E");
  876.         return fFalse;
  877.       }
  878.       SwitchF(us.fEphemeris);
  879.       if (ch1 == 'y')
  880.         us.nEphemYears = us.fEphemeris ? 1 : 0;
  881.       else if (ch1 == 'Y') {
  882.         i = atoi(argv[1]);
  883.         if (i < 1) {
  884.           ErrorValN("EY", i);
  885.           return fFalse;
  886.         }
  887.         us.nEphemYears = i;
  888.       }
  889.       break;
  890.  
  891.     case 'e':
  892.       SwitchF(us.fListing); SwitchF(us.fWheel);
  893.       SwitchF(us.fGrid); SwitchF(us.fAspList); SwitchF(us.fMidpoint);
  894.       SwitchF(us.fHorizon); SwitchF(us.fOrbit);
  895.       SwitchF(us.fAstroGraph); SwitchF(us.fInfluence); SwitchF(us.fCalendar);
  896.       SwitchF(us.fInDay); SwitchF(us.fInDayInf);
  897.       SwitchF(us.fEphemeris);
  898.       SwitchF(us.fGridConfig); SwitchF(us.fInfluenceSign);
  899.       SwitchF(us.fLatitudeCross);
  900.       break;
  901.  
  902.     case 't':
  903.       SwitchF(us.fTransit);
  904.       Zon2 = us.zonDef; Dst2 = us.dstDef; Lon2 = us.lonDef; Lat2 = us.latDef;
  905.       if (ch1 == 'p') {
  906.         is.fProgress = fTrue;
  907.         ch1 = argv[0][++ich];
  908.       }
  909.       if (i = (ch1 == 'y') + 2*(ch1 == 'Y'))
  910.         ch1 = argv[0][++ich];
  911. #ifdef TIME
  912.       if (ch1 == 'n') {
  913.         GetTimeNow(&Mon2, &Day2, &Yea2, &Tim2, Zon2-Dst2);
  914.         if (i == 1)
  915.           Mon2 = 0;
  916.         else if (i > 1) {
  917.           Mon2 = -1; Day2 = NParseSz(argv[1], pmDay);
  918.         }
  919.         break;
  920.       }
  921. #endif
  922.       if (argc <= 2 - (i & 1)) {
  923.         ErrorArgc("t");
  924.         return fFalse;
  925.       }
  926.       if (i) {
  927.         if (i == 1)
  928.           Mon2 = 0;
  929.         else {
  930.           Mon2 = -1; Day2 = NParseSz(argv[2], pmDay);
  931.         }
  932.       } else {
  933.         Mon2 = NParseSz(argv[1], pmMon);
  934.         if (!FValidMon(Mon2)) {
  935.           ErrorValN("t", Mon2);
  936.           return fFalse;
  937.         }
  938.       }
  939.       Yea2 = NParseSz(argv[2 - (i > 0)], pmYea);
  940.       argc -= 2 - (i & 1); argv += 2 - (i & 1);
  941.       break;
  942.  
  943.     case 'T':
  944.       SwitchF(us.fTransitInf);
  945.       Zon2 = us.zonDef; Dst2 = us.dstDef; Lon2 = us.lonDef; Lat2 = us.latDef;
  946.       if (ch1 == 'p') {
  947.         is.fProgress = fTrue;
  948.         ch1 = argv[0][++ich];
  949.       }
  950. #ifdef TIME
  951.       if (ch1 == 'n') {
  952.         GetTimeNow(&Mon2, &Day2, &Yea2, &Tim2, Zon2-Dst2);
  953.         break;
  954.       }
  955. #endif
  956.       if (argc <= 3) {
  957.         ErrorArgc("T");
  958.         return fFalse;
  959.       }
  960.       Mon2 = NParseSz(argv[1], pmMon);
  961.       Day2 = NParseSz(argv[2], pmDay);
  962.       Yea2 = NParseSz(argv[3], pmYea);
  963.       if (!FValidMon(Mon2)) {
  964.         ErrorValN("T", Mon2);
  965.         return fFalse;
  966.       } else if (!FValidDay(Day2, Mon2, Yea2)) {
  967.         ErrorValN("T", Day2);
  968.         return fFalse;
  969.       } else if (!FValidYea(Yea2)) {
  970.         ErrorValN("T", Yea2);
  971.         return fFalse;
  972.       }
  973.       argc -= 3; argv += 3;
  974.       break;
  975.  
  976. #ifdef ARABIC
  977.     case 'P':
  978.       if (argc > 1 && (i = atoi(argv[1]))) {
  979.         argc--; argv++;
  980.         if (!FValidPart(i)) {
  981.           ErrorValN("P", i);
  982.           return fFalse;
  983.         }
  984.         us.nArabicParts = i;
  985.       }
  986.       if (ch1 == 'z' || ch1 == 'n' || ch1 == 'f') {
  987.         us.nArabic = ch1;
  988.         ch1 = ch2;
  989.       } else
  990.         SwitchF(us.nArabic);
  991.       if (ch1 == '0')
  992.         SwitchF(us.fArabicFlip);
  993.       break;
  994. #endif
  995.  
  996. #ifdef INTERPRET
  997.     case 'I':
  998.       if (argc > 1 && (i = atoi(argv[1]))) {
  999.         argc--; argv++;
  1000.         if (!FValidScreen(i)) {
  1001.           ErrorValN("I", i);
  1002.           return fFalse;
  1003.         }
  1004.         us.nScreenWidth = i;
  1005.       }
  1006.       SwitchF(us.fInterpret);
  1007.       break;
  1008. #endif
  1009.  
  1010.     /* Switches which affect how the chart parameters are obtained: */
  1011.  
  1012. #ifdef TIME
  1013.     case 'n':
  1014.       FInputData(szNowCore);
  1015.       if (ch1 == 'd')
  1016.         TT = 0.0;
  1017.       else if (ch1 == 'm') {
  1018.         DD = 1; TT = 0.0;
  1019.       } else if (ch1 == 'y') {
  1020.         MM = DD = 1; TT = 0.0;
  1021.       }
  1022.       break;
  1023. #endif
  1024.  
  1025.     case 'z':
  1026.       if (ch1 == '0') {
  1027.         if (argc <= 1 || RParseSz(argv[1], pmZon) == rLarge) {
  1028.           i = us.dstDef != 0.0;
  1029.           SwitchF(i);
  1030.           SS = us.dstDef = i ? 1.0 : 0.0;
  1031.         } else {
  1032.           SS = us.dstDef = RParseSz(argv[1], pmZon);
  1033.           if (!FValidDst(us.dstDef)) {
  1034.             ErrorValR("z0", us.dstDef);
  1035.             return fFalse;
  1036.           }
  1037.           argc--; argv++;
  1038.         }
  1039.         break;
  1040.       } else if (ch1 == 'l') {
  1041.         if (argc <= 2) {
  1042.           ErrorArgc("zl");
  1043.           return fFalse;
  1044.         }
  1045.         OO = us.lonDef = RParseSz(argv[1], pmLon);
  1046.         AA = us.latDef = RParseSz(argv[2], pmLat);
  1047.         if (!FValidLon(us.lonDef)) {
  1048.           ErrorValR("zl", us.lonDef);
  1049.           return fFalse;
  1050.         } else if (!FValidLat(us.latDef)) {
  1051.           ErrorValR("zl", us.latDef);
  1052.           return fFalse;
  1053.         }
  1054.         argc -= 2; argv += 2;
  1055.         break;
  1056.       } else if (ch1 == 't') {
  1057.         if (argc <= 1) {
  1058.           ErrorArgc("zt");
  1059.           return fFalse;
  1060.         }
  1061.         TT = RParseSz(argv[1], pmTim);
  1062.         if (!FValidTim(TT)) {
  1063.           ErrorValR("zt", TT);
  1064.           return fFalse;
  1065.         }
  1066.         argc--; argv++;
  1067.         break;
  1068.       } else if (ch1 == 'd') {
  1069.         if (argc <= 1) {
  1070.           ErrorArgc("zd");
  1071.           return fFalse;
  1072.         }
  1073.         DD = NParseSz(argv[1], pmDay);
  1074.         if (!FValidDay(DD, MM, YY)) {
  1075.           ErrorValN("zd", DD);
  1076.           return fFalse;
  1077.         }
  1078.         argc--; argv++;
  1079.         break;
  1080.       } else if (ch1 == 'i') {
  1081.         if (argc <= 2) {
  1082.           ErrorArgc("zi");
  1083.           return fFalse;
  1084.         }
  1085.         ciCore.nam = SzPersist(argv[1]);
  1086.         ciCore.loc = SzPersist(argv[2]);
  1087.         argc -= 2; argv += 2;
  1088.         break;
  1089.       }
  1090.       if (argc <= 1 || RParseSz(argv[1], pmZon) == rLarge)
  1091.         ZZ -= 1.0;
  1092.       else {
  1093.         ZZ = us.zonDef = RParseSz(argv[1], pmZon);
  1094.         if (!FValidZon(us.zonDef)) {
  1095.           ErrorValR("z", us.zonDef);
  1096.           return fFalse;
  1097.         }
  1098.         argc--; argv++;
  1099.       }
  1100.       break;
  1101.  
  1102.     case 'q':
  1103.       i = (ch1 == 'y' || ch1 == 'j') + 2*(ch1 == 'm') + 3*(ch1 == 'd') +
  1104.         4*(ch1 == chNull) + 7*(ch1 == 'a') + 8*(ch1 == 'b');
  1105.       if (argc <= i) {
  1106.         ErrorArgc("q");
  1107.         return fFalse;
  1108.       }
  1109.       is.fHaveInfo = fTrue;
  1110.       if (ch1 == 'j') {
  1111.         is.JD = atof(argv[1])+rRound;
  1112.         TT = RFract(is.JD);
  1113.         JulianToMdy(is.JD-TT, &MM, &DD, &YY);
  1114.         TT = DegToDec(TT * 24.0);
  1115.         SS = ZZ = 0.0; OO = us.lonDef; AA = us.latDef;
  1116.       } else {
  1117.         MM = i > 1 ? NParseSz(argv[1], pmMon) : 1;
  1118.         DD = i > 2 ? NParseSz(argv[2], pmDay) : 1;
  1119.         YY = NParseSz(argv[3-(i<3)-(i<2)], pmYea);
  1120.         TT = i > 3 ? RParseSz(argv[4], pmTim) : (i < 3 ? 0.0 : 12.0);
  1121.         SS = i > 7 ? RParseSz(argv[5], pmDst) : (i > 6 ? 0.0 : us.dstDef);
  1122.         ZZ = i > 6 ? RParseSz(argv[5 + (i > 7)], pmZon) : us.zonDef;
  1123.         OO = i > 6 ? RParseSz(argv[6 + (i > 7)], pmLon) : us.lonDef;
  1124.         AA = i > 6 ? RParseSz(argv[7 + (i > 7)], pmLat) : us.latDef;
  1125.         if (!FValidMon(MM)) {
  1126.           ErrorValN("q", MM);
  1127.           return fFalse;
  1128.         } else if (!FValidDay(DD, MM, YY)) {
  1129.           ErrorValN("q", DD);
  1130.           return fFalse;
  1131.         } else if (!FValidYea(YY)) {
  1132.           ErrorValN("q", YY);
  1133.           return fFalse;
  1134.         } else if (!FValidTim(TT)) {
  1135.           ErrorValR("q", TT);
  1136.           return fFalse;
  1137.         } else if (!FValidDst(SS)) {
  1138.           ErrorValR("q", SS);
  1139.           return fFalse;
  1140.         } else if (!FValidZon(ZZ)) {
  1141.           ErrorValR("a", ZZ);
  1142.           return fFalse;
  1143.         } else if (!FValidLon(OO)) {
  1144.           ErrorValR("a", OO);
  1145.           return fFalse;
  1146.         } else if (!FValidLat(AA)) {
  1147.           ErrorValR("a", AA);
  1148.           return fFalse;
  1149.         }
  1150.       }
  1151.       argc -= i; argv += i;
  1152.       break;
  1153.  
  1154.     case 'i':
  1155.       if (argc <= 1) {
  1156.         ErrorArgc("i");
  1157.         return fFalse;
  1158.       }
  1159.       if (!FInputData(argv[1]))
  1160.         return fFalse;
  1161.       argc--; argv++;
  1162.       break;
  1163.  
  1164.     case '>':
  1165.       ch1 = 's';
  1166.       /* Fall through */
  1167.  
  1168.     case 'o':
  1169.       if (argc <= 1) {
  1170.         ErrorArgc("o");
  1171.         return fFalse;
  1172.       }
  1173.       if (ch1 == 's') {
  1174.         is.szFileScreen = SzPersist(argv[1]);
  1175.         argc--; argv++;
  1176.         break;
  1177.       } else if (ch1 == '0')
  1178.         SwitchF(us.fWritePos);
  1179.       SwitchF(us.fWriteFile);
  1180.       is.szFileOut = SzPersist(argv[1]);
  1181.       if (is.fSzPersist) {
  1182.         is.rgszComment = argv;
  1183.         do {
  1184.           argc--; argv++;
  1185.           is.cszComment++;
  1186.         } while (argc > 1 && !FChSwitch(argv[1][0]));
  1187.       }
  1188.       break;
  1189.  
  1190.     /* Switches which affect what information is used in a chart: */
  1191.  
  1192.     case 'R':
  1193.       if (ch1 == 'A') {
  1194.         while (argc > 1 && (i = NParseSz(argv[1], pmAspect)))
  1195.           if (!FAspect(i)) {
  1196.             ErrorValN("RA", i);
  1197.             return fFalse;
  1198.           } else {
  1199.             aspectorb[i] = -rDegHalf;
  1200.             argc--; argv++;
  1201.           }
  1202.         break;
  1203.       }
  1204.       if (ch1 == 'T') {
  1205.         pch = (char *)ignore2;
  1206.         ch1 = argv[0][++ich];
  1207.       } else
  1208.         pch = (char *)ignore;
  1209.       if (ch1 == '0')
  1210.         for (i = 1; i <= cObj; i++)
  1211.           pch[i] = fTrue;
  1212.       else if (ch1 == '1') {
  1213.         for (i = 1; i <= cObj; i++)
  1214.           pch[i] = fFalse;
  1215.         us.fCusp = us.fUranian = us.nStar = fTrue;
  1216.       } else if (ch1 == 'C')
  1217.         for (i = cuspLo; i <= cuspHi; i++)
  1218.           SwitchF(pch[i]);
  1219.       else if (ch1 == 'u')
  1220.         for (i = uranLo; i <= uranHi; i++)
  1221.           SwitchF(pch[i]);
  1222.       else if (ch1 == 'U')
  1223.         for (i = starLo; i <= starHi; i++)
  1224.           SwitchF(pch[i]);
  1225.       else if (argc <= 1 || (!NParseSz(argv[1], pmObject))) {
  1226.         for (i = oChi; i <= oVes; i++)
  1227.           SwitchF(pch[i]);
  1228.         for (i = oLil; i <= oEP; i++)
  1229.           SwitchF(pch[i]);
  1230.       }
  1231.       while (argc > 1 && (i = NParseSz(argv[1], pmObject)))
  1232.         if (!FItem(i)) {
  1233.           ErrorValN("R", i);
  1234.           return fFalse;
  1235.         } else {
  1236.           SwitchF(pch[i]);
  1237.           argc--; argv++;
  1238.         }
  1239.       break;
  1240.  
  1241.     case 'C':
  1242.       SwitchF(us.fCusp);
  1243.       break;
  1244.  
  1245.     case 'u':
  1246.       SwitchF(us.fUranian);
  1247.       break;
  1248.  
  1249.     case 'U':
  1250.       if (ch1 == 'n' || ch1 == 'b' || ch1 == 'z' || ch1 == 'l')
  1251.         us.nStar = ch1;
  1252.       else
  1253.         SwitchF(us.nStar);
  1254.       break;
  1255.  
  1256.     case 'A':
  1257.       if (ch1 != 'o' && ch1 != 'm' && ch1 != 'd' && ch1 != 'a') {
  1258.         if (argc <= 1) {
  1259.           ErrorArgc("A");
  1260.           return fFalse;
  1261.         }
  1262.         i = NParseSz(argv[1], pmAspect);
  1263.         if (!FValidAspect(i)) {
  1264.           ErrorValN("A", i);
  1265.           return fFalse;
  1266.         }
  1267.         us.nAsp = i;
  1268.         argc--; argv++;
  1269.       } else {
  1270.         if (argc <= 2) {
  1271.           ErrorArgc("A");
  1272.           return fFalse;
  1273.         }
  1274.         i = NParseSz(argv[1], ch1 == 'o' || ch1 == 'a' ? pmAspect : pmObject);
  1275.         if (i < 1 || i > (ch1 == 'o' || ch1 == 'a' ? cAspect : oNorm)) {
  1276.           ErrorValN("A", i);
  1277.           return fFalse;
  1278.         }
  1279.         rT = RParseSz(argv[2], 0);
  1280.         if (rT < -rDegMax || rT > rDegMax) {
  1281.           ErrorValR("A", rT);
  1282.           return fFalse;
  1283.         }
  1284.         if (ch1 == 'o')
  1285.           aspectorb[i] = rT;
  1286.         else if (ch1 == 'm')
  1287.           planetorb[i] = rT;
  1288.         else if (ch1 == 'd')
  1289.           planetadd[i] = rT;
  1290.         else
  1291.           aspectangle[i] = rT;
  1292.         argc -= 2; argv += 2;
  1293.       }
  1294.       break;
  1295.  
  1296.     /* Switches which affect how a chart is computed: */
  1297.  
  1298.     case 'b':
  1299.       if (ch1 == '0')
  1300.         SwitchF(us.fSeconds);
  1301. #ifdef PLACALC
  1302.       SwitchF(us.fPlacalc);
  1303. #endif
  1304.       is.fSeconds = us.fSeconds;
  1305.       break;
  1306.  
  1307.     case 'c':
  1308.       if (argc <= 1) {
  1309.         ErrorArgc("c");
  1310.         return fFalse;
  1311.       }
  1312.       i = NParseSz(argv[1], pmSystem);
  1313.       if (!FValidSystem(i)) {
  1314.         ErrorValN("c", i);
  1315.         return fFalse;
  1316.       }
  1317.       us.nHouseSystem = i;
  1318.       argc--; argv++;
  1319.       break;
  1320.  
  1321.     case 's':
  1322.       if (argc > 1 && ((rT = atof(argv[1])) != 0.0 || FNumCh(argv[1][0]))) {
  1323.         argc--; argv++;
  1324.         us.rZodiacOffset = rT;
  1325.       }
  1326.       if (ch1 == 'r')
  1327.         SwitchF(us.fEquator);
  1328.       else if (ch1 == 'h')
  1329.         us.nDegForm = 1;
  1330.       else if (ch1 == 'd')
  1331.         us.nDegForm = 2;
  1332.       else if (ch1 == 'z')
  1333.         us.nDegForm = 0;
  1334.       else
  1335.         SwitchF(us.fSiderial);
  1336.       break;
  1337.  
  1338.     case 'h':
  1339.       if (argc > 1 && (i = NParseSz(argv[1], pmObject))) {
  1340.         argc--; argv++;
  1341.       } else
  1342.         i = 1;
  1343.       if (i < 0 || i == oMoo || !FObject(i) || i > uranHi) {
  1344.         ErrorValN("h", i);
  1345.         return fFalse;
  1346.       }
  1347.       us.objCenter = i;
  1348.       pch = szObjName[0];
  1349.       szObjName[0] = szObjName[us.objCenter];
  1350.       szObjName[us.objCenter] = pch;
  1351.       if (us.objCenter < oMoo)
  1352.         us.objCenter = 1-us.objCenter;
  1353.       break;
  1354.  
  1355.     case 'p':
  1356.       if (fAnd) {
  1357.         us.fProgress = fFalse;
  1358.         break;
  1359.       }
  1360.       if (ch1 == '0') {
  1361.         SwitchF(us.fSolarArc);
  1362.         ch1 = (argv[0][++ich]);
  1363.       }
  1364.       us.fProgress = fTrue;
  1365. #ifdef TIME
  1366.       if (ch1 == 'n') {
  1367.         GetTimeNow(&Mon, &Day, &Yea, &Tim, us.zonDef - us.dstDef);
  1368.         is.JDp = MdytszToJulian(Mon, Day, Yea, Tim, us.dstDef, us.zonDef);
  1369.         break;
  1370.       }
  1371. #endif
  1372.       if (ch1 == 'd') {
  1373.         if (argc <= 1) {
  1374.           ErrorArgc("pd");
  1375.           return fFalse;
  1376.         }
  1377.         us.rProgDay = atof(argv[1]);
  1378.         if (us.rProgDay == 0.0) {
  1379.           ErrorValR("pd", us.rProgDay);
  1380.           return fFalse;
  1381.         }
  1382.         argc--; argv++;
  1383.         break;
  1384.       }
  1385.       if (argc <= 3) {
  1386.         ErrorArgc("p");
  1387.         return fFalse;
  1388.       }
  1389.       Mon = NParseSz(argv[1], pmMon);
  1390.       Day = NParseSz(argv[2], pmDay);
  1391.       Yea = NParseSz(argv[3], pmYea);
  1392.       if (!FValidMon(Mon)) {
  1393.         ErrorValN("p", Mon);
  1394.         return fFalse;
  1395.       } else if (!FValidDay(Day, Mon, Yea)) {
  1396.         ErrorValN("p", Day);
  1397.         return fFalse;
  1398.       } else if (!FValidYea(Yea)) {
  1399.         ErrorValN("p", Yea);
  1400.         return fFalse;
  1401.       }
  1402.       is.JDp = MdytszToJulian(Mon, Day, Yea, 0.0, us.dstDef, us.zonDef);
  1403.       argc -= 3; argv += 3;
  1404.       break;
  1405.  
  1406.     case 'x':
  1407.       if (argc <= 1) {
  1408.         ErrorArgc("x");
  1409.         return fFalse;
  1410.       }
  1411.       i = atoi(argv[1]);
  1412.       if (!FValidHarmonic(i)) {
  1413.         ErrorValN("x", i);
  1414.         return fFalse;
  1415.       }
  1416.       us.nHarmonic = i;
  1417.       argc--; argv++;
  1418.       break;
  1419.  
  1420.     case '1':
  1421.       if (argc > 1 && (i = NParseSz(argv[1], pmObject))) {
  1422.         argc--; argv++;
  1423.       } else
  1424.         i = oSun;
  1425.       if (!FItem(i)) {
  1426.         ErrorValN("1", i);
  1427.         return fFalse;
  1428.       }
  1429.       us.objOnAsc = fAnd ? 0 : i;
  1430.       break;
  1431.  
  1432.     case '2':
  1433.       if (argc > 1 && (i = NParseSz(argv[1], pmObject))) {
  1434.         argc--; argv++;
  1435.       } else
  1436.         i = oSun;
  1437.       if (!FItem(i)) {
  1438.         ErrorValN("2", i);
  1439.         return fFalse;
  1440.       }
  1441.       us.objOnAsc = fAnd ? 0 : -i;
  1442.       break;
  1443.  
  1444.     case '3':
  1445.       SwitchF(us.fDecan);
  1446.       break;
  1447.  
  1448.     case 'f':
  1449.       SwitchF(us.fFlip);
  1450.       break;
  1451.  
  1452.     case 'G':
  1453.       SwitchF(us.fGeodetic);
  1454.       break;
  1455.  
  1456.     case 'F':
  1457.       if (argc <= 3) {
  1458.         ErrorArgc("F");
  1459.         return fFalse;
  1460.       }
  1461.       i = NParseSz(argv[1], pmObject);
  1462.       if (!FItem(i)) {
  1463.         ErrorValN("F", i);
  1464.         return fFalse;
  1465.       }
  1466.       force[i] = (NParseSz(argv[2], pmSign)-1.0)*30.0+DecToDeg(atof(argv[3]));
  1467.       if (force[i] < 0.0 || force[i] >= rDegMax) {
  1468.         ErrorValR("F", force[i]);
  1469.         return fFalse;
  1470.       } else
  1471.         force[i] += rDegMax;
  1472.       argc -= 3; argv += 3;
  1473.       break;
  1474.  
  1475.     case '+':
  1476.       if (argc > 1 && (i = atoi(argv[1])) != 0) {
  1477.         argc--; argv++;
  1478.       } else
  1479.         i = 1;
  1480.       us.dayDelta += i * (ch1 == 'y' ? 365 : (ch1 == 'm' ? 30 : 1));
  1481.       break;
  1482.  
  1483.     case '-': case chNull:
  1484.       if (argc > 1 && (i = atoi(argv[1])) != 0) {
  1485.         argc--; argv++;
  1486.       } else
  1487.         i = 1;
  1488.       us.dayDelta -= i * (ch1 == 'y' ? 365 : (ch1 == 'm' ? 30 : 1));
  1489.       break;
  1490.  
  1491.     /* Switches for relationship and comparison charts: */
  1492.  
  1493.     case 'r':
  1494.       if (fAnd) {
  1495.         us.nRel = 0;
  1496.         break;
  1497.       }
  1498.       i = 2 + 2*((ch1 == 'c' || ch1 == 'm') && ch2 == '0');
  1499.       if (argc <= i) {
  1500.         ErrorArgc("r");
  1501.         return fFalse;
  1502.       }
  1503.       if (ch1 == 'c')
  1504.         us.nRel = rcComposite;
  1505.       else if (ch1 == 'm')
  1506.         us.nRel = rcMidpoint;
  1507.       else if (ch1 == 'd')
  1508.         us.nRel = rcDifference;
  1509. #ifdef BIORHYTHM
  1510.       else if (ch1 == 'b')
  1511.         us.nRel = rcBiorhythm;
  1512. #endif
  1513.       else if (ch1 == '0')
  1514.         us.nRel = rcDual;
  1515.       else if (ch1 == 't')
  1516.         us.nRel = rcTransit;
  1517.       else if (ch1 == 'p') {
  1518.         us.nRel = rcProgress;
  1519.         us.fSolarArc = (ch2 == '0');
  1520.       } else
  1521.         us.nRel = rcSynastry;
  1522.       is.szFile = SzPersist(argv[1]); is.szFile2 = SzPersist(argv[2]);
  1523.       if (is.fSzInteract) {
  1524.         if (!FInputData(is.szFile2))
  1525.           return fFalse;
  1526.         ciTwin = ciCore;
  1527.         if (!FInputData(is.szFile))
  1528.           return fFalse;
  1529.       }
  1530.       if (i > 2) {
  1531.         us.nRatio1 = atoi(argv[3]);
  1532.         us.nRatio2 = atoi(argv[4]);
  1533.         if (us.nRatio1 == us.nRatio2)
  1534.           us.nRatio1 = us.nRatio2 = 1;
  1535.       }
  1536.       argc -= i; argv += i;
  1537.       break;
  1538.  
  1539. #ifdef TIME
  1540.     case 'y':
  1541.       if (argc <= 1) {
  1542.         ErrorArgc("y");
  1543.         return fFalse;
  1544.       }
  1545.       if (ch1 == 'd')
  1546.         us.nRel = rcDifference;
  1547. #ifdef BIORHYTHM
  1548.       else if (ch1 == 'b')
  1549.         us.nRel = rcBiorhythm;
  1550. #endif
  1551.       else if (ch1 == 't')
  1552.         us.nRel = rcTransit;
  1553.       else if (ch1 == 'p') {
  1554.         us.nRel = rcProgress;
  1555.         if (ch2 == '0')
  1556.           SwitchF(us.fSolarArc);
  1557.       } else
  1558.         us.nRel = rcDual;
  1559.       is.szFile = SzPersist(argv[1]); is.szFile2 = szNowCore;
  1560.       argc--; argv++;
  1561.       break;
  1562. #endif
  1563.  
  1564.     /* Switches to access graphics options: */
  1565.  
  1566.     case 'k':
  1567.       if (ch1 == '0')
  1568.         us.fAnsi = 2;
  1569.       else
  1570.         SwitchF(us.fAnsi);
  1571.       break;
  1572.  
  1573. #ifdef PCG
  1574.     case 'V':
  1575.       if (argc <= 1) {
  1576.         ErrorArgc("V");
  1577.         return fFalse;
  1578.       }
  1579.       i = atoi(argv[1]);
  1580.       if (!FValidTextrows(i)) {
  1581.         ErrorValN("V", i);
  1582.         return fFalse;
  1583.       }
  1584.       gs.nTextRows = i;
  1585.       argc--; argv++;
  1586.       break;
  1587. #endif
  1588.  
  1589. #ifdef GRAPH
  1590.     case 'X':
  1591.       i = NProcessSwitchesX(argc, argv, ich, fOr, fAnd, fNot);
  1592.       if (i < 0)
  1593.         return fFalse;
  1594.       SwitchF2(us.fGraphics);
  1595.       argc -= i; argv += i;
  1596.       break;
  1597. #endif
  1598.  
  1599.     case ';':    /* The -; switch means don't process the rest of the line. */
  1600.       return fTrue;
  1601.  
  1602.     case '@':    /* The -@ switch is just a system flag indicator no-op. */
  1603.       break;
  1604.  
  1605.     case '.':                /* "-." is usually used to exit the -Q loop. */
  1606.       Terminate(tcForce);
  1607.  
  1608.     case 'B':                /* For no useful reason, -B sounds a beep. */
  1609.       putchar(chBell);
  1610.       break;
  1611.  
  1612.     default:
  1613.       ErrorSwitch(argv[0]);
  1614.       return fFalse;
  1615.     }
  1616.     argc--; argv++;
  1617.   }
  1618.   return fTrue;
  1619. }
  1620.  
  1621.  
  1622. /*
  1623. ******************************************************************************
  1624. ** Main Program.
  1625. ******************************************************************************
  1626. */
  1627.  
  1628. #ifndef NOMAIN
  1629. /* The main program, the starting point for Astrolog, follows. This routine */
  1630. /* basically consists of a loop, inside which we read a command line, and   */
  1631. /* go process it, before actually calling a routine to do the neat stuff.   */
  1632.  
  1633. #ifdef SWITCHES
  1634. void main(argc, argv)
  1635. int argc;
  1636. char **argv;
  1637. {
  1638. #else
  1639. void main()
  1640. {
  1641.   int argc;
  1642.   char **argv;
  1643. #endif
  1644.   char szCommandLine[cchSzMax], *rgsz[MAXSWITCHES];
  1645.  
  1646.   /* Read in info from the astrolog.dat file. */
  1647.   FProcessSwitchFile(DEFAULT_INFOFILE, NULL);
  1648.  
  1649. LBegin:
  1650. #ifdef PCG
  1651.   if (gs.nTextRows > 0) {
  1652.     PcSetTextRows(gs.nTextRows);
  1653.     neg(gs.nTextRows);
  1654.   }
  1655. #endif
  1656.   if (us.fNoSwitches) {                             /* Go prompt for    */
  1657.     argc = NPromptSwitches(szCommandLine, rgsz);    /* switches if we   */
  1658.     argv = rgsz;                                    /* don't have them. */
  1659.   }
  1660.   is.szProgName = argv[0];
  1661.   is.fSzPersist = fTrue;
  1662.   if (FProcessSwitches(argc, argv)) {
  1663.     if (!us.fNoSwitches && us.fLoopInit) {
  1664.       us.fNoSwitches = fTrue;
  1665.       goto LBegin;
  1666.     }
  1667. #ifdef PCG
  1668.     if (gs.nTextRows > 0) {
  1669.       PcSetTextRows(gs.nTextRows);
  1670.       neg(gs.nTextRows);
  1671.     }
  1672. #endif
  1673.     Action();
  1674.   }
  1675.   if (us.fLoop) {       /* If -Q in effect, loop back and get switch */
  1676.     PrintL2();          /* information for another chart to display. */
  1677.     InitVariables();
  1678.     us.fLoop = us.fNoSwitches = fTrue;
  1679.     goto LBegin;
  1680.   }
  1681.   Terminate(tcOK);    /* The only standard place to exit Astrolog is here. */
  1682. }
  1683. #endif /* NOMAIN */
  1684.  
  1685. /* astrolog.c */
  1686.